import React, { useState, useRef, useEffect } from 'react'
import { Button, Input, message } from 'antd'
import { SendOutlined, DeleteOutlined, SoundOutlined, SoundFilled, PlayCircleOutlined } from '@ant-design/icons'
import CryptoJS from 'crypto-js'
import './index.css'
import { useTranslation } from 'react-i18next'

interface Message {
  role: 'user' | 'assistant'
  content: string
  timestamp: number
}

interface ChatBotProps {
  appId?: string
  apiKey?: string
  apiSecret?: string
  recognizedText: string
}

const ChatBot: React.FC<ChatBotProps> = ({
  appId = import.meta.env.VITE_CHAT_APPID, // 从环境变量读取
  apiKey = import.meta.env.VITE_CHAT_API_KEY, // 从环境变量读取
  apiSecret = import.meta.env.VITE_CHAT_API_SECRET, // 从环境变量读取
  recognizedText
}) => {
  const [messages, setMessages] = useState<Message[]>([])
  const [inputValue, setInputValue] = useState('')
  const [isConnecting, setIsConnecting] = useState(false)
  const [isReceiving, setIsReceiving] = useState(false)
  const [isAutoSpeechEnabled, setIsAutoSpeechEnabled] = useState(true) // 自动朗读开关
  const [isSpeaking, setIsSpeaking] = useState(false) // 是否正在朗读
  const wsRef = useRef<WebSocket | null>(null)
  const messagesEndRef = useRef<HTMLDivElement>(null)
  const lastRecognizedTextRef = useRef<string>('')
  const speechSynthesisRef = useRef<SpeechSynthesisUtterance | null>(null)
  const voicesRef = useRef<SpeechSynthesisVoice[]>([])
  const [hasActivatedSpeech, setHasActivatedSpeech] = useState(false)

  // 自动滚动到底部
  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }

  useEffect(() => {
    // 预加载语音列表并在用户交互后解锁语音合成
    if (!('speechSynthesis' in window)) return
    const loadVoices = () => {
      const voices = speechSynthesis.getVoices()
      if (voices && voices.length) {
        voicesRef.current = voices
        // console.log('可用语音列表:', voices.map(v => `${v.name}(${v.lang})`))
      }
    }
    loadVoices()
    speechSynthesis.addEventListener('voiceschanged', loadVoices)

    const handleUserActivation = () => {
      try {
        speechSynthesis.resume()
        setHasActivatedSpeech(true)
      } catch { }
      document.removeEventListener('click', handleUserActivation)
      document.removeEventListener('keydown', handleUserActivation)
    }
    document.addEventListener('click', handleUserActivation, { once: true })
    document.addEventListener('keydown', handleUserActivation, { once: true })

    return () => {
      speechSynthesis.removeEventListener('voiceschanged', loadVoices)
      document.removeEventListener('click', handleUserActivation)
      document.removeEventListener('keydown', handleUserActivation)
    }
  }, [])


  // 语音合成朗读功能
  const speakText = (text: string) => {
    if (!text || !isAutoSpeechEnabled) return

    // 检查浏览器是否支持语音合成
    if (!('speechSynthesis' in window)) {
      console.error('浏览器不支持语音合成功能')
      message.error('您的浏览器不支持语音合成功能')
      return
    }

    // 停止当前朗读
    if (speechSynthesisRef.current) {
      speechSynthesis.cancel()
    }

    try {
      const utterance = new SpeechSynthesisUtterance(text)
      speechSynthesisRef.current = utterance

      // 设置语音参数（优先中文）
      utterance.lang = 'zh-CN'
      utterance.rate = 0.95
      utterance.pitch = 1
      utterance.volume = 1

      const selectVoice = () => {
        const voices = voicesRef.current.length ? voicesRef.current : speechSynthesis.getVoices()
        if (voices && voices.length) {
          const zhVoice = voices.find(v => v.lang && v.lang.toLowerCase().startsWith('zh'))
            || voices.find(v => v.lang && v.lang.toLowerCase().includes('cn'))
          if (zhVoice) {
            utterance.voice = zhVoice
            utterance.lang = zhVoice.lang
          } else {
            // 回退到第一个可用语音
            utterance.voice = voices[0]
            utterance.lang = voices[0].lang || utterance.lang
          }
        }
      }
      selectVoice()

      // 朗读事件监听
      utterance.onstart = () => {
        setIsSpeaking(true)
        try { window.dispatchEvent(new CustomEvent('ai-speech', { detail: { speaking: true } })) } catch { }
        console.log('开始朗读:', text.substring(0, 50) + '...')
      }

      utterance.onend = () => {
        setIsSpeaking(false)
        try { window.dispatchEvent(new CustomEvent('ai-speech', { detail: { speaking: false } })) } catch { }
        console.log('朗读完成')
      }

      utterance.onerror = (event) => {
        setIsSpeaking(false)
        console.error('朗读错误:', event.error)
        message.error(`朗读失败: ${event.error}`)
      }

      // 确保语音服务就绪
      const currentVoices = speechSynthesis.getVoices()
      if (!currentVoices || currentVoices.length === 0) {
        // 等待语音列表加载后再朗读，并进行一次语音选择
        const onVoicesReady = () => {
          console.log('语音列表已加载，开始朗读')
          selectVoice()
          speechSynthesis.speak(utterance)
        }
        speechSynthesis.addEventListener('voiceschanged', onVoicesReady, { once: true })
      } else {
        // 如果浏览器因策略暂停，尝试恢复
        try { speechSynthesis.resume() } catch { }
        speechSynthesis.speak(utterance)
      }

      console.log('语音合成请求已发送')
    } catch (error) {
      console.error('语音合成失败:', error)
      message.error('语音合成功能不可用')
      setIsSpeaking(false)
    }
  }

  // 切换自动朗读开关
  const toggleAutoSpeech = () => {
    setIsAutoSpeechEnabled(prev => {
      const newState = !prev
      if (!newState) {
        stopSpeaking() // 关闭时停止当前朗读
      } else {
        // 开启时尝试恢复语音系统
        try { speechSynthesis.resume() } catch { }
      }
      message.success(newState ? '已开启自动朗读' : '已关闭自动朗读')
      return newState
    })
  }

  // 停止朗读
  const stopSpeaking = () => {
    if (speechSynthesisRef.current) {
      speechSynthesis.cancel()
      setIsSpeaking(false)
      try { window.dispatchEvent(new CustomEvent('ai-speech', { detail: { speaking: false } })) } catch { }
    }
  }

  // 手动测试朗读功能
  const testSpeech = () => {
    const testText = "这是语音合成测试，如果您能听到这段话，说明朗读功能正常工作。"
    console.log('手动测试朗读功能')
    speakText(testText)
  }
  useEffect(() => {
    scrollToBottom()
  }, [messages])
  const hasCredentials = Boolean(appId && apiKey && apiSecret)
  // 监听语音识别文字变化，自动发送消息
  useEffect(() => {
    if (recognizedText && recognizedText.trim() && recognizedText !== lastRecognizedTextRef.current) {
      console.log('检测到新的语音识别文字:', recognizedText)
      lastRecognizedTextRef.current = recognizedText
      // 延迟发送，确保语音识别完成
      const timer = setTimeout(() => {
        if (!hasCredentials) {
          message.error('语音识别自动发送失败：未配置星火 API 凭据')
          return
        }
        if (['。', '！', '?', '.', '!'].includes(recognizedText.trim())) return
        sendMessage(recognizedText.trim())
      }, 500)
      return () => clearTimeout(timer)
    }
  }, [recognizedText])
  // 生成WebSocket URL
  const getWebSocketUrl = (): Promise<string> => {
    return new Promise((resolve, reject) => {
      try {
        if (!hasCredentials) {
          reject(new Error('缺少星火 API 凭据'))
          return
        }
        const url = 'wss://spark-api.xf-yun.com/v3.5/chat' // Spark Max URL
        const host = 'spark-api.xf-yun.com'
        const date = new Date().toUTCString()
        const algorithm = 'hmac-sha256'
        const headers = 'host date request-line'
        const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v3.5/chat HTTP/1.1`
        const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret as string)
        const signature = CryptoJS.enc.Base64.stringify(signatureSha)
        const authorizationOrigin = `api_key="${apiKey as string}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
        const authorization = btoa(authorizationOrigin)
        const finalUrl = `${url}?authorization=${authorization}&date=${date}&host=${host}`
        resolve(finalUrl)
      } catch (error) {
        reject(error)
      }
    })
  }
  // 发送消息（支持自定义消息内容）
  const sendMessage = async (customMessage?: string) => {
    const messageContent = customMessage || inputValue.trim()
    if (!messageContent) {
      if (!customMessage) {
        message.warning('请输入消息内容')
      }
      return
    }
    if (!hasCredentials) {
      message.error('发送消息失败：未配置星火 API 凭据')
      return
    }
    const userMessage: Message = {
      role: 'user',
      content: messageContent,
      timestamp: Date.now()
    }
    // 用户在输入框发送消息时，派发数字人指令事件（避免语音自动发送重复触发）
    if (!customMessage) {
      try { window.dispatchEvent(new CustomEvent('avatar-command', { detail: { command: messageContent } })) } catch { }
      console.log('从聊天输入派发头像指令:', messageContent)
    }
    setMessages(prev => [...prev, userMessage])
    if (!customMessage) {
      setInputValue('')
    }
    setIsConnecting(true)
    try {
      const wsUrl = await getWebSocketUrl()
      wsRef.current = new WebSocket(wsUrl)
      wsRef.current.onopen = () => {
        console.log('WebSocket连接已建立')
        setIsConnecting(false)
        setIsReceiving(true)
        // 构建历史消息（包含当前用户消息）
        const allMessages = [...messages, userMessage]
        const chatMessages = allMessages.map(msg => ({
          role: msg.role,
          content: msg.content
        }))
        // 发送请求参数
        const params = {
          header: {
            app_id: appId,
            uid: 'user_' + Date.now()
          },
          parameter: {
            chat: {
              domain: 'generalv3.5', // Spark Max domain
              temperature: 0.7,
              max_tokens: 2048
            }
          },
          payload: {
            message: {
              text: chatMessages
            }
          }
        }
        wsRef.current?.send(JSON.stringify(params))
        console.log('发送请求参数:', params)
      }
      let assistantMessage = ''
      wsRef.current.onmessage = (event) => {
        const data = JSON.parse(event.data)
        console.log('收到响应:', data)
        if (data.header.code === 0) {
          if (data.payload && data.payload.choices && data.payload.choices.text) {
            const content = data.payload.choices.text[0].content
            assistantMessage += content
            // 实时更新助手消息
            setMessages(prev => {
              const newMessages = [...prev]
              const lastMessage = newMessages[newMessages.length - 1]
              if (lastMessage && lastMessage.role === 'assistant') {
                // 更新现有助手消息
                lastMessage.content = assistantMessage
              } else {
                // 添加新的助手消息
                newMessages.push({
                  role: 'assistant',
                  content: assistantMessage,
                  timestamp: Date.now()
                })
              }
              return newMessages
            })
          }
          // 检查是否为最后一条消息
          if (data.header.status === 2) {
            console.log('对话完成')
            setIsReceiving(false)
            wsRef.current?.close()

            // AI回复完成后自动朗读
            if (assistantMessage.trim() && isAutoSpeechEnabled) {
              setTimeout(() => {
                speakText(assistantMessage)
              }, 300) // 延迟300ms确保UI更新完成
            }
          }
        } else {
          console.error('API错误:', data.header.message)
          message.error(`对话失败: ${data.header.message}`)
          setIsReceiving(false)
        }
      }
      wsRef.current.onerror = (error) => {
        console.error('WebSocket错误:', error)
        message.error('连接失败，请检查网络或API配置')
        setIsConnecting(false)
        setIsReceiving(false)
      }
      wsRef.current.onclose = () => {
        console.log('WebSocket连接已关闭')
        setIsConnecting(false)
        setIsReceiving(false)
      }
    } catch (error) {
      console.error('发送消息失败:', error)
      message.error('发送消息失败，请重试')
      setIsConnecting(false)
      setIsReceiving(false)
    }
  }
  // 清空对话
  const clearMessages = () => {
    setMessages([])
    stopSpeaking() // 清空对话时停止朗读
    if (wsRef.current) {
      wsRef.current.close()
    }
    setIsConnecting(false)
    setIsReceiving(false)
  }
  // 处理回车发送
  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      sendMessage()
    }
  }
  const { t } = useTranslation()
  return (
    <div className="chatbot-container">
      <div className="chatbot-header">
        <h3>{t('chat_title')}</h3>
        <div className="header-controls">
          <Button
            icon={<PlayCircleOutlined />}
            onClick={testSpeech}
            size="small"
            type="text"
            title={t('test_speech_title')}
            style={{ marginRight: 8 }}
          />
          <Button
            icon={isAutoSpeechEnabled ? <SoundFilled /> : <SoundOutlined />}
            onClick={toggleAutoSpeech}
            size="small"
            type={isAutoSpeechEnabled ? "primary" : "text"}
            title={isAutoSpeechEnabled ? t('auto_speech_off_title') : t('auto_speech_on_title')}
            style={{ marginRight: 8 }}
          />
          {isSpeaking && (
            <Button
              onClick={stopSpeaking}
              size="small"
              type="text"
              title={t('stop')}
              style={{ marginRight: 8, color: '#ff4d4f' }}
            >
              {t('stop')}
            </Button>
          )}
          <Button
            icon={<DeleteOutlined />}
            onClick={clearMessages}
            size="small"
            type="text"
            title={t('clear')}
          />
        </div>
      </div>
      <div className="chatbot-messages">
        {messages.length === 0 ? (
          <div className="empty-state">
            <p>{t('start_chat')}</p>
          </div>
        ) : (
          messages.map((msg, index) => (
            <div key={index} className={`message ${msg.role}`}>
              <div className="message-content">
                <div className="message-text">{msg.content}</div>
                <div className="message-time">
                  {new Date(msg.timestamp).toLocaleTimeString()}
                </div>
              </div>
            </div>
          ))
        )}
        {isReceiving && (
          <div className="message assistant">
            <div className="message-content">
              <div className="typing-indicator">
                <span></span>
                <span></span>
                <span></span>
              </div>
            </div>
          </div>
        )}
        <div ref={messagesEndRef} />
      </div>
      <div className="chatbot-input">
        <Input.TextArea
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onKeyPress={handleKeyPress}
          placeholder={t('input_placeholder')}
          autoSize={{ minRows: 1, maxRows: 4 }}
          disabled={isConnecting || isReceiving}
        />
        <Button
          type="primary"
          icon={<SendOutlined />}
          onClick={() => sendMessage()}
          loading={isConnecting}
          disabled={isReceiving || !inputValue.trim()}
        >
          {isConnecting ? t('connecting') : isReceiving ? t('replying') : t('send')}
        </Button>
      </div>
    </div>
  )
}
export default ChatBot